package cn.cdeden.knowledge.controller.personalChat;

import cn.cdeden.common.core.domain.R;
import cn.cdeden.common.satoken.utils.LoginHelper;
import cn.cdeden.knowledge.domain.QaFilesTree;
import cn.cdeden.knowledge.domain.UserMessage;
import cn.cdeden.knowledge.domain.dto.AnalyzeFileDto;
import cn.cdeden.knowledge.service.QaFilesTreeService;
import cn.cdeden.knowledge.utils.ReaderUtil;
import cn.cdeden.resource.api.RemoteFileService;
import cn.cdeden.system.api.RemoteConfigService;
import cn.cdeden.system.api.RemoteLargeModelService;
import cn.cdeden.system.api.domain.vo.RemoteLargeModelVo;
import cn.cdeden.system.api.model.LoginUser;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;


/**
 * 个人知识库对话模块
 */
@RestController
@RequestMapping("/personal/chat")
@RequiredArgsConstructor
public class personalAiChatController {

    @DubboReference(check = false)
    private final RemoteFileService remoteFileService;

    @DubboReference(check = false)
    private final RemoteLargeModelService remoteLargeModelService;

    @DubboReference(check = false)
    private final RemoteConfigService remoteConfigService;

    private final QaFilesTreeService qaFilesTreeService;


    /**
     * 获取文档markdown格式
     * @param storageId
     * @return
     * @throws IOException
     */
    @GetMapping("/markDown")
    public String getMarkDownText(@RequestParam(value = "storageId", required = false) String storageId, @RequestParam(value = "fileName", required = false) String fileName) throws IOException {
        LoginUser loginUser = LoginHelper.getLoginUser();
        //根据storageId查询文件的真实id
        QaFilesTree qaFilesTree = qaFilesTreeService.getOne(new LambdaQueryWrapper<QaFilesTree>()
            .eq(QaFilesTree::getRealName, fileName)
            .eq(QaFilesTree::getCreateId, loginUser.getUserId().toString())
            .orderByDesc(QaFilesTree::getCreateTime).last("LIMIT 1"));

        String fileUrl = remoteFileService.selectUrlByIds(qaFilesTree.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        return ReaderUtil.markItDown(fileUrl, markItDownUrl);
    }

    //合同抽取

    /**
     * 合同抽取
     * @param fileName
     * @param fileType
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    public String contractExtraction(@RequestParam(value = "fileName", required = false) String fileName,
                                     @RequestParam(value = "fileType", required = false) String fileType) throws IOException, InterruptedException {

        LoginUser loginUser = LoginHelper.getLoginUser();

        //根据storageId查询文件的真实id
        QaFilesTree qaFilesTree = qaFilesTreeService.getOne(new LambdaQueryWrapper<QaFilesTree>()
            .eq(QaFilesTree::getRealName, fileName)
            .eq(QaFilesTree::getCreateId, loginUser.getUserId().toString())
            .orderByDesc(QaFilesTree::getCreateTime).last("LIMIT 1"));

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(qaFilesTree.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        HttpURLConnection markItDownConnection = null;
        String prompt = null;

        switch (fileType.toLowerCase()) {
            case "txt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pdf":
                //查询MinerU的url
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                //调用MinerU识别PDF文件中的内容
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "doc":
            case "docx":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "xlsx":
            case "xls":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pptx":
            case "ppt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + fileType);
        }

        // 创建用于 POST 请求的 data 对象
        JSONObject data = new JSONObject();

        //查询选择的模型
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();


        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", false);
        data.set("prompt", "如下是一份合同文本，请抽取其中的关键信息以如下范本格式返回相应的值" + "范本格式：" +
            "卖方公司名称：" +
            "卖家地址：" +
            "卖家联系电话：" +
            "买方公司名称：" +
            "买方地址：" +
            "买家联系电话：" +
            "产品名称：" +
            "产品型号：" +
            "产品颜色：" +
            "产品数量：" +
            "产品单价：" +
            "产品总价：" +
            "交货地点：" +
            "交货日期：" +
            "交货运输成本：" +
            "交货风险转移：" +
            "付款金额：" +
            "付款截止日期：" +
            "付款方式：" +
            "保修期限：" +
            "保修服务详情：" +
            "卖方违约罚款金额：" +
            "卖方违约条件：" +
            "买方违约罚款金额：" +
            "买方违约条件：" +
            "争议解决方法：" +
            "争议解决法院管辖权：" +
            "合同生效日期：" +
            "卖家签名：" +
            "买方签名：" +
            "合同文本如下：" +
            prompt  +
            "注意你最后只需要回复补全的数据不要包含任何其他的内容，并且补全的内容要转化成markdown中的表格形式");

        HttpURLConnection connection = null;

        //查询url
        String ollamaUrl = remoteLargeModelVo.getConfigValue();
        URL url = new URL(ollamaUrl + "/api/generate");
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        // 发送请求数据
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = data.toString().getBytes("UTF-8");
            os.write(input, 0, input.length);
        }

        // 检查响应码
        int status = connection.getResponseCode();
        if (status != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP request failed with status code " + status);
        }

        // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
        StringBuilder response = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                JSONObject body = new JSONObject(line);
                String responseText = body.getStr("response", "");
                response.append(responseText).append("\n");
                // 检查是否有错误信息
                if (body.containsKey("error")) {
                    throw new IOException("Error in response: " + body.getStr("error"));
                }
            }
        }

        String s = response.toString();
        s = s.replaceAll("```|markdown", "");
        return s;
    }

    //招标文件抽取
    public String extractionOfBiddingDocuments(@RequestParam(value = "fileName", required = false) String fileName,
                                               @RequestParam(value = "fileType", required = false) String fileType) throws IOException, InterruptedException{
        LoginUser loginUser = LoginHelper.getLoginUser();

        //根据storageId查询文件的真实id
        QaFilesTree qaFilesTree = qaFilesTreeService.getOne(new LambdaQueryWrapper<QaFilesTree>()
            .eq(QaFilesTree::getRealName, fileName)
            .eq(QaFilesTree::getCreateId, loginUser.getUserId().toString())
            .orderByDesc(QaFilesTree::getCreateTime).last("LIMIT 1"));

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(qaFilesTree.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        HttpURLConnection markItDownConnection = null;
        String prompt = null;

        switch (fileType.toLowerCase()) {
            case "txt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pdf":
                //查询MinerU的url
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                //调用MinerU识别PDF文件中的内容
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "doc":
            case "docx":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "xlsx":
            case "xls":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pptx":
            case "ppt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + fileType);
        }

        // 创建用于 POST 请求的 data 对象
        JSONObject data = new JSONObject();

        //查询选择的模型
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();


        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", false);
        data.set("prompt", "如下是一份合同文本，请抽取其中的关键信息以如下范本格式返回相应的值" + "范本格式：" +
            "甲方：" +
            "甲方联系方式：" +
            "乙方：" +
            "乙方联系方式：" +
            "合同金额：" +
            "付款方式：" +
            "合同日期：" +
            "合同文本如下：" +
            prompt
            + "注意你最后只需要回复补全的数据不要包含任何其他的内容，并且补全的内容要转化成markdown中的表格形式");

        HttpURLConnection connection = null;

        //查询url
        String ollamaUrl = remoteLargeModelVo.getConfigValue();
        URL url = new URL(ollamaUrl + "/api/generate");
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        // 发送请求数据
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = data.toString().getBytes("UTF-8");
            os.write(input, 0, input.length);
        }

        // 检查响应码
        int status = connection.getResponseCode();
        if (status != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP request failed with status code " + status);
        }

        // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
        StringBuilder response = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                JSONObject body = new JSONObject(line);
                String responseText = body.getStr("response", "");
                response.append(responseText).append("\n");
                // 检查是否有错误信息
                if (body.containsKey("error")) {
                    throw new IOException("Error in response: " + body.getStr("error"));
                }
            }
        }

        String s = response.toString();
        s = s.replaceAll("```|markdown", "");
        return s;
    }

    //自定义抽取

    /**
     * 自定义抽取
     * @param fileName
     * @param fileType
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    public String customExtraction(@RequestParam(value = "fileName", required = false) String fileName,
                                   @RequestParam(value = "fileType", required = false) String fileType) throws IOException, InterruptedException{
        LoginUser loginUser = LoginHelper.getLoginUser();

        //根据storageId查询文件的真实id
        QaFilesTree qaFilesTree = qaFilesTreeService.getOne(new LambdaQueryWrapper<QaFilesTree>()
            .eq(QaFilesTree::getRealName, fileName)
            .eq(QaFilesTree::getCreateId, loginUser.getUserId().toString())
            .orderByDesc(QaFilesTree::getCreateTime).last("LIMIT 1"));

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(qaFilesTree.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        HttpURLConnection markItDownConnection = null;
        String prompt = null;

        switch (fileType.toLowerCase()) {
            case "txt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pdf":
                //查询MinerU的url
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                //调用MinerU识别PDF文件中的内容
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "doc":
            case "docx":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "xlsx":
            case "xls":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pptx":
            case "ppt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + fileType);
        }

        // 创建用于 POST 请求的 data 对象
        JSONObject data = new JSONObject();

        //查询选择的模型
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();


        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", false);
        data.set("prompt", prompt +
            prompt
            + "注意你最后只需要回复补全的数据不要包含任何其他的内容，并且补全的内容要转化成markdown中的表格形式");

        HttpURLConnection connection = null;

        //查询url
        String ollamaUrl = remoteLargeModelVo.getConfigValue();
        URL url = new URL(ollamaUrl + "/api/generate");
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        // 发送请求数据
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = data.toString().getBytes("UTF-8");
            os.write(input, 0, input.length);
        }

        // 检查响应码
        int status = connection.getResponseCode();
        if (status != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP request failed with status code " + status);
        }

        // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
        StringBuilder response = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                JSONObject body = new JSONObject(line);
                String responseText = body.getStr("response", "");
                response.append(responseText).append("\n");
                // 检查是否有错误信息
                if (body.containsKey("error")) {
                    throw new IOException("Error in response: " + body.getStr("error"));
                }
            }
        }

        String s = response.toString();
        s = s.replaceAll("```|markdown", "");
        return s;
    }



    //合同校审

    /**
     * 合同校审
     * @param fileName
     * @param fileType
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    public String contractReview(@RequestParam(value = "fileName", required = false) String fileName,
                                 @RequestParam(value = "fileType", required = false) String fileType) throws IOException, InterruptedException{
        LoginUser loginUser = LoginHelper.getLoginUser();

        //根据storageId查询文件的真实id
        QaFilesTree qaFilesTree = qaFilesTreeService.getOne(new LambdaQueryWrapper<QaFilesTree>()
            .eq(QaFilesTree::getRealName, fileName)
            .eq(QaFilesTree::getCreateId, loginUser.getUserId().toString())
            .orderByDesc(QaFilesTree::getCreateTime).last("LIMIT 1"));

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(qaFilesTree.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        HttpURLConnection markItDownConnection = null;
        String prompt = null;

        switch (fileType.toLowerCase()) {
            case "txt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pdf":
                //查询MinerU的url
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                //调用MinerU识别PDF文件中的内容
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "doc":
            case "docx":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "xlsx":
            case "xls":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pptx":
            case "ppt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + fileType);
        }

        // 创建用于 POST 请求的 data 对象
        JSONObject data = new JSONObject();

        //查询选择的模型
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();


        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", false);
        data.set("prompt", "如下是一份合同文本，请根据采购合同和国家法律法规校审合同的内容提示我不合理的地方" +
            "范本格式：" +
            prompt
            + "注意回答的是干净的markdown文本");

        HttpURLConnection connection = null;

        //查询url
        String ollamaUrl = remoteLargeModelVo.getConfigValue();
        URL url = new URL(ollamaUrl + "/api/generate");
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        // 发送请求数据
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = data.toString().getBytes("UTF-8");
            os.write(input, 0, input.length);
        }

        // 检查响应码
        int status = connection.getResponseCode();
        if (status != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP request failed with status code " + status);
        }

        // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
        StringBuilder response = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                JSONObject body = new JSONObject(line);
                String responseText = body.getStr("response", "");
                response.append(responseText).append("\n");
                // 检查是否有错误信息
                if (body.containsKey("error")) {
                    throw new IOException("Error in response: " + body.getStr("error"));
                }
            }
        }

        String s = response.toString();
        s = s.replaceAll("```|markdown", "");
        return s;
    }

    //标书校审
    public String bidReview(@RequestParam(value = "fileName", required = false) String fileName,
                            @RequestParam(value = "fileType", required = false) String fileType) throws IOException, InterruptedException {
        LoginUser loginUser = LoginHelper.getLoginUser();

        //根据storageId查询文件的真实id
        QaFilesTree qaFilesTree = qaFilesTreeService.getOne(new LambdaQueryWrapper<QaFilesTree>()
            .eq(QaFilesTree::getRealName, fileName)
            .eq(QaFilesTree::getCreateId, loginUser.getUserId().toString())
            .orderByDesc(QaFilesTree::getCreateTime).last("LIMIT 1"));

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(qaFilesTree.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        HttpURLConnection markItDownConnection = null;
        String prompt = null;

        switch (fileType.toLowerCase()) {
            case "txt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pdf":
                //查询MinerU的url
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                //调用MinerU识别PDF文件中的内容
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "doc":
            case "docx":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "xlsx":
            case "xls":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pptx":
            case "ppt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + fileType);
        }

        // 创建用于 POST 请求的 data 对象
        JSONObject data = new JSONObject();

        //查询选择的模型
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();


        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", false);
        data.set("prompt", "如下是一份标书，请根据标书文件和国家法律法规校审文件的内容提示我不合理的地方" +
            "范本格式：" +
            prompt
            + "注意回答的是干净的markdown文本");

        HttpURLConnection connection = null;

        //查询url
        String ollamaUrl = remoteLargeModelVo.getConfigValue();
        URL url = new URL(ollamaUrl + "/api/generate");
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        // 发送请求数据
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = data.toString().getBytes("UTF-8");
            os.write(input, 0, input.length);
        }

        // 检查响应码
        int status = connection.getResponseCode();
        if (status != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP request failed with status code " + status);
        }

        // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
        StringBuilder response = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                JSONObject body = new JSONObject(line);
                String responseText = body.getStr("response", "");
                response.append(responseText).append("\n");
                // 检查是否有错误信息
                if (body.containsKey("error")) {
                    throw new IOException("Error in response: " + body.getStr("error"));
                }
            }
        }

        String s = response.toString();
        s = s.replaceAll("```|markdown", "");
        return s;
    }


    //自定义校审

    /**
     *
     * @param fileName
     * @param fileType
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    public String customReview(@RequestParam(value = "fileName", required = false) String fileName,
                               @RequestParam(value = "fileType", required = false) String fileType) throws IOException, InterruptedException  {
        LoginUser loginUser = LoginHelper.getLoginUser();

        //根据storageId查询文件的真实id
        QaFilesTree qaFilesTree = qaFilesTreeService.getOne(new LambdaQueryWrapper<QaFilesTree>()
            .eq(QaFilesTree::getRealName, fileName)
            .eq(QaFilesTree::getCreateId, loginUser.getUserId().toString())
            .orderByDesc(QaFilesTree::getCreateTime).last("LIMIT 1"));

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(qaFilesTree.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        HttpURLConnection markItDownConnection = null;
        String prompt = null;

        switch (fileType.toLowerCase()) {
            case "txt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pdf":
                //查询MinerU的url
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                //调用MinerU识别PDF文件中的内容
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "doc":
            case "docx":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "xlsx":
            case "xls":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pptx":
            case "ppt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + fileType);
        }

        // 创建用于 POST 请求的 data 对象
        JSONObject data = new JSONObject();

        //查询选择的模型
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();


        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", false);
        data.set("prompt", prompt +
            "范本格式：" +
            prompt
            + "注意回答的是干净的markdown文本");

        HttpURLConnection connection = null;

        //查询url
        String ollamaUrl = remoteLargeModelVo.getConfigValue();
        URL url = new URL(ollamaUrl + "/api/generate");
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        // 发送请求数据
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = data.toString().getBytes("UTF-8");
            os.write(input, 0, input.length);
        }

        // 检查响应码
        int status = connection.getResponseCode();
        if (status != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP request failed with status code " + status);
        }

        // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
        StringBuilder response = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                JSONObject body = new JSONObject(line);
                String responseText = body.getStr("response", "");
                response.append(responseText).append("\n");
                // 检查是否有错误信息
                if (body.containsKey("error")) {
                    throw new IOException("Error in response: " + body.getStr("error"));
                }
            }
        }

        String s = response.toString();
        s = s.replaceAll("```|markdown", "");
        return s;
    }



    //流程图

    /**
     * markdown显示成流程图
     * @return
     * @throws IOException
     */
    @GetMapping("/flowChart")
    public String getFlowChart(@RequestParam("fileName") String fileName, @RequestParam("fileType") String fileType) throws IOException, InterruptedException {
        //根据storageId查询文件的真实id
        QaFilesTree qaFilesTree = qaFilesTreeService.getOne(new LambdaQueryWrapper<QaFilesTree>()
            .eq(QaFilesTree::getRealName, fileName)
            .orderByDesc(QaFilesTree::getCreateTime).last("LIMIT 1"));

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(qaFilesTree.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        HttpURLConnection markItDownConnection = null;
        String prompt = null;

        switch (fileType.toLowerCase()) {
            case "txt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pdf":
//                prompt = ReaderUtil.readPdf(fileUrl);
                //查询MinerU的url
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                //调用MinerU识别PDF文件中的内容
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "doc":
            case "docx":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readWord(fileUrl);
                break;
            case "xlsx":
            case "xls":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readExcel(fileUrl);
                break;
            case "pptx":
            case "ppt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + fileType);
        }

        // 创建用于 POST 请求的 data 对象
        JSONObject data = new JSONObject();

        //查询选择的模型
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();


//        String checkType = remoteLargeModelService.selectConfigByKey("check_type");
//        String model = remoteLargeModelService.selectConfigByTypeKey("model", checkType);

        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", false);
//        data.set("prompt", "请将后面的内容转换成Mermaid流程图的格式注意是纯文本的内容，不要包含其他任何格式例如markdown，注意只回复最终的纯文本格式的内容不要包含任何其他内容" + prompt);
        data.set("prompt", "请将后面的内容转换成Mermaid流程图格式。注意：仅返回纯文本的Mermaid格式，不要包含其他任何内容，如markdown等格式。确保生成的内容仅为Mermaid流程图文本，不需要其他额外说明或格式。内容如下：\n\n" + prompt);

        HttpURLConnection connection = null;

        //查询url
//        String ollamaUrl = remoteLargeModelService.selectConfigByTypeKey("url", checkType);
        String ollamaUrl = remoteLargeModelVo.getConfigValue();
        URL url = new URL(ollamaUrl + "/api/generate");
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        // 发送请求数据
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = data.toString().getBytes("UTF-8");
            os.write(input, 0, input.length);
        }

        // 检查响应码
        int status = connection.getResponseCode();
        if (status != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP request failed with status code " + status);
        }

        // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
        StringBuilder response = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                JSONObject body = new JSONObject(line);
                String responseText = body.getStr("response", "");
                response.append(responseText).append("\n");
                // 检查是否有错误信息
                if (body.containsKey("error")) {
                    throw new IOException("Error in response: " + body.getStr("error"));
                }
            }
        }

        String s = response.toString();
        s = s.replaceAll("```|mermaid", "");
        return s;

    }
    //时序图

    /**
     * 显示时序图
     * @param fileName
     * @param fileType
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    @GetMapping("/timingDiagram")
    public String getTimingDiagram(@RequestParam("fileName") String fileName, @RequestParam("fileType") String fileType) throws IOException, InterruptedException {
        //根据storageId查询文件的真实id
        QaFilesTree qaFilesTree = qaFilesTreeService.getOne(new LambdaQueryWrapper<QaFilesTree>()
            .eq(QaFilesTree::getRealName, fileName)
            .orderByDesc(QaFilesTree::getCreateTime).last("LIMIT 1"));

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(qaFilesTree.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        HttpURLConnection markItDownConnection = null;
        String prompt = null;

        switch (fileType.toLowerCase()) {
            case "txt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pdf":
//                prompt = ReaderUtil.readPdf(fileUrl);
                //查询MinerU的url
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                //调用MinerU识别PDF文件中的内容
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "doc":
            case "docx":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readWord(fileUrl);
                break;
            case "xlsx":
            case "xls":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readExcel(fileUrl);
                break;
            case "pptx":
            case "ppt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + fileType);
        }

        // 创建用于 POST 请求的 data 对象
        JSONObject data = new JSONObject();

        //查询选择的模型
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();

//        String checkType = remoteLargeModelService.selectConfigByKey("check_type");
//        String model = remoteLargeModelService.selectConfigByTypeKey("model", checkType);

        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", true);
        data.set("prompt", "请将后面的内容转换成Mermaid时序图格式。注意：仅返回纯文本的Mermaid格式，不要包含其他任何内容，如markdown等格式。确保生成的内容仅为Mermaid时序图文本，不需要其他额外说明或格式。内容如下：\n\n" + prompt);

        HttpURLConnection connection = null;

        //查询url
//        String ollamaUrl = remoteLargeModelService.selectConfigByTypeKey("url", checkType);
        String ollamaUrl = remoteLargeModelVo.getConfigValue();
        URL url = new URL(ollamaUrl + "/api/generate");
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        // 发送请求数据
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = data.toString().getBytes("UTF-8");
            os.write(input, 0, input.length);
        }

        // 检查响应码
        int status = connection.getResponseCode();
        if (status != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP request failed with status code " + status);
        }

        // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
        StringBuilder response = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                JSONObject body = new JSONObject(line);
                String responseText = body.getStr("response", "");
                response.append(responseText).append("\n");
                // 检查是否有错误信息
                if (body.containsKey("error")) {
                    throw new IOException("Error in response: " + body.getStr("error"));
                }
            }
        }

        return response.toString();
    }

    //类图

    /**
     * 显示类图
     * @param fileName
     * @param fileType
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    @GetMapping("/classDiagram")
    public String getClassDiagram(@RequestParam("fileName") String fileName, @RequestParam("fileType") String fileType) throws IOException, InterruptedException {
        //根据storageId查询文件的真实id
        QaFilesTree qaFilesTree = qaFilesTreeService.getOne(new LambdaQueryWrapper<QaFilesTree>()
            .eq(QaFilesTree::getRealName, fileName)
            .orderByDesc(QaFilesTree::getCreateTime).last("LIMIT 1"));

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(qaFilesTree.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        HttpURLConnection markItDownConnection = null;
        String prompt = null;

        switch (fileType.toLowerCase()) {
            case "txt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pdf":
//                prompt = ReaderUtil.readPdf(fileUrl);
                //查询MinerU的url
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                //调用MinerU识别PDF文件中的内容
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "doc":
            case "docx":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readWord(fileUrl);
                break;
            case "xlsx":
            case "xls":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readExcel(fileUrl);
                break;
            case "pptx":
            case "ppt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + fileType);
        }

        // 创建用于 POST 请求的 data 对象
        JSONObject data = new JSONObject();

        //查询选择的模型
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();

//        String checkType = remoteLargeModelService.selectConfigByKey("check_type");
//        String model = remoteLargeModelService.selectConfigByTypeKey("model", checkType);

        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", true);
        data.set("prompt", "请将后面的内容转换成Mermaid类图格式。注意：仅返回纯文本的Mermaid格式，不要包含其他任何内容，如markdown等格式。确保生成的内容仅为Mermaid类图文本，不需要其他额外说明或格式。内容如下：\n\n" + prompt);

        HttpURLConnection connection = null;

        //查询url
        String ollamaUrl = remoteLargeModelVo.getConfigValue();
        URL url = new URL(ollamaUrl + "/api/generate");
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        // 发送请求数据
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = data.toString().getBytes("UTF-8");
            os.write(input, 0, input.length);
        }

        // 检查响应码
        int status = connection.getResponseCode();
        if (status != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP request failed with status code " + status);
        }

        // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
        StringBuilder response = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                JSONObject body = new JSONObject(line);
                String responseText = body.getStr("response", "");
                response.append(responseText).append("\n");
                // 检查是否有错误信息
                if (body.containsKey("error")) {
                    throw new IOException("Error in response: " + body.getStr("error"));
                }
            }
        }

        return response.toString();
    }

    //状态图

    /**
     * 显示状态图
     * @param fileName
     * @param fileType
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    @GetMapping("/stateDiagram")
    public String getStateDiagram(@RequestParam("fileName") String fileName, @RequestParam("fileType") String fileType) throws IOException, InterruptedException {
        //根据storageId查询文件的真实id
        QaFilesTree qaFilesTree = qaFilesTreeService.getOne(new LambdaQueryWrapper<QaFilesTree>()
            .eq(QaFilesTree::getRealName, fileName)
            .orderByDesc(QaFilesTree::getCreateTime).last("LIMIT 1"));

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(qaFilesTree.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        HttpURLConnection markItDownConnection = null;
        String prompt = null;

        switch (fileType.toLowerCase()) {
            case "txt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pdf":
//                prompt = ReaderUtil.readPdf(fileUrl);
                //查询MinerU的url
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                //调用MinerU识别PDF文件中的内容
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "doc":
            case "docx":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readWord(fileUrl);
                break;
            case "xlsx":
            case "xls":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readExcel(fileUrl);
                break;
            case "pptx":
            case "ppt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + fileType);
        }

        // 创建用于 POST 请求的 data 对象
        JSONObject data = new JSONObject();

        //查询选择的模型
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();

//        String checkType = remoteLargeModelService.selectConfigByKey("check_type");
//        String model = remoteLargeModelService.selectConfigByTypeKey("model", checkType);

        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", true);
        data.set("prompt", "请将后面的内容转换成Mermaid状态图格式。注意：仅返回纯文本的Mermaid格式，不要包含其他任何内容，如markdown等格式。确保生成的内容仅为Mermaid状态图文本，不需要其他额外说明或格式。内容如下：\n\n" + prompt);

        HttpURLConnection connection = null;

        //查询url
        String ollamaUrl = remoteLargeModelVo.getConfigValue();
        URL url = new URL(ollamaUrl + "/api/generate");
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        // 发送请求数据
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = data.toString().getBytes("UTF-8");
            os.write(input, 0, input.length);
        }

        // 检查响应码
        int status = connection.getResponseCode();
        if (status != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP request failed with status code " + status);
        }

        // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
        StringBuilder response = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                JSONObject body = new JSONObject(line);
                String responseText = body.getStr("response", "");
                response.append(responseText).append("\n");
                // 检查是否有错误信息
                if (body.containsKey("error")) {
                    throw new IOException("Error in response: " + body.getStr("error"));
                }
            }
        }

        return response.toString();
    }

    //实体关系图

    /**
     * 显示实体关系图
     * @param fileName
     * @param fileType
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    @GetMapping("/entityRelationshipDiagram")
    public String getEntityRelationshipDiagram(@RequestParam("fileName") String fileName, @RequestParam("fileType") String fileType) throws IOException, InterruptedException {
        //根据storageId查询文件的真实id
        QaFilesTree qaFilesTree = qaFilesTreeService.getOne(new LambdaQueryWrapper<QaFilesTree>()
            .eq(QaFilesTree::getRealName, fileName)
            .orderByDesc(QaFilesTree::getCreateTime).last("LIMIT 1"));

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(qaFilesTree.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        HttpURLConnection markItDownConnection = null;
        String prompt = null;

        switch (fileType.toLowerCase()) {
            case "txt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pdf":
//                prompt = ReaderUtil.readPdf(fileUrl);
                //查询MinerU的url
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                //调用MinerU识别PDF文件中的内容
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "doc":
            case "docx":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readWord(fileUrl);
                break;
            case "xlsx":
            case "xls":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readExcel(fileUrl);
                break;
            case "pptx":
            case "ppt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + fileType);
        }

        // 创建用于 POST 请求的 data 对象
        JSONObject data = new JSONObject();

        //查询选择的模型
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();

//        String checkType = remoteLargeModelService.selectConfigByKey("check_type");
//        String model = remoteLargeModelService.selectConfigByTypeKey("model", checkType);

        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", true);
        data.set("prompt", "请将后面的内容转换成Mermaid实体关系图格式。注意：仅返回纯文本的Mermaid格式，不要包含其他任何内容，如markdown等格式。确保生成的内容仅为Mermaid实体关系图文本，不需要其他额外说明或格式。内容如下：\n\n" + prompt);

        HttpURLConnection connection = null;

        //查询url
        String ollamaUrl = remoteLargeModelVo.getConfigValue();
        URL url = new URL(ollamaUrl + "/api/generate");
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        // 发送请求数据
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = data.toString().getBytes("UTF-8");
            os.write(input, 0, input.length);
        }

        // 检查响应码
        int status = connection.getResponseCode();
        if (status != HttpURLConnection.HTTP_OK) {
            throw new IOException("HTTP request failed with status code " + status);
        }

        // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
        StringBuilder response = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                JSONObject body = new JSONObject(line);
                String responseText = body.getStr("response", "");
                response.append(responseText).append("\n");
                // 检查是否有错误信息
                if (body.containsKey("error")) {
                    throw new IOException("Error in response: " + body.getStr("error"));
                }
            }
        }

        return response.toString();
    }


    /**
     * AI总结
     * @param userMessage
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    @PostMapping("/document/summary")
    public SseEmitter getDocumentarySummary(@RequestBody UserMessage userMessage) throws IOException, InterruptedException {

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(userMessage.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        HttpURLConnection markItDownConnection = null;
        String prompt = null;

        switch (userMessage.getFileType().toLowerCase()) {
            case "txt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
                break;
            case "pdf":
//                prompt = ReaderUtil.readPdf(fileUrl);
                //查询MinerU的url
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                //调用MinerU识别PDF文件中的内容
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "doc":
            case "docx":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readWord(fileUrl);
                break;
            case "xlsx":
            case "xls":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readExcel(fileUrl);
                break;
            case "pptx":
            case "ppt":
                prompt =  ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + userMessage.getFileType());
        }

        // 创建用于 POST 请求的 data 对象
        JSONObject data = new JSONObject();

        //查询选择的模型
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();

//        String checkType = remoteLargeModelService.selectConfigByKey("check_type");
//        String model = remoteLargeModelService.selectConfigByTypeKey("model", checkType);

        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", true);
        data.set("prompt", "请对后面的内容进行总结，注意只回复总结的内容不要包含其他任何内容" + prompt);

        HttpURLConnection connection = null;

        // 使用 SseEmitter 来进行流式响应
        SseEmitter emitter = new SseEmitter();

        try {
            //查询url
            String ollamaUrl = remoteLargeModelVo.getConfigValue();
            URL url = new URL(ollamaUrl + "/api/generate");
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setDoOutput(true);

            // 发送请求数据
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = data.toString().getBytes("UTF-8");
                os.write(input, 0, input.length);
            }

            // 检查响应码
            int status = connection.getResponseCode();
            if (status != HttpURLConnection.HTTP_OK) {
                throw new IOException("HTTP request failed with status code " + status);
            }

            // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
            try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                String line;
                while ((line = br.readLine()) != null) {
                    JSONObject body = new JSONObject(line);
                    String responseText = body.getStr("response", "");

                    // 发送数据到前端
                    emitter.send(responseText, MediaType.TEXT_PLAIN);

                    // 检查是否有错误信息
                    if (body.containsKey("error")) {
                        throw new IOException("Error in response: " + body.getStr("error"));
                    }
                }
            }

        } catch (Exception e) {
            emitter.completeWithError(e);
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }

        // 完成后端响应
        emitter.complete();
        return emitter;

    }


    /**
     * AI翻译
     * @param userMessage
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    @PostMapping("/documentary/translation")
    public SseEmitter getDocumentaryTranslation(@RequestBody UserMessage userMessage) throws IOException, InterruptedException {

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(userMessage.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        String prompt = null;

        switch (userMessage.getFileType().toLowerCase()) {
            case "txt":
                prompt = ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readTextFile(fileUrl);
                break;
            case "pdf":
//                prompt = ReaderUtil.readPdf(fileUrl);
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "docx":
            case "doc":
                prompt = ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readWord(fileUrl);
                break;
            case "xlsx":
            case "xls":
                prompt = ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readExcel(fileUrl);
                break;
            case "pptx":
            case "ppt":
                prompt = ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + userMessage.getFileType());
        }

        //查询使用的模型
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();


//        String checkType = remoteLargeModelService.selectConfigByKey("check_type");
//        String model = remoteLargeModelService.selectConfigByTypeKey("model", checkType);
//        String ollamaUrl = remoteLargeModelService.selectConfigByTypeKey("url", checkType);

        // 创建用于 POST 请求的 data 对象
        JSONObject data = new JSONObject();
        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", true);
        data.set("prompt", "请对后面的内容进行翻译，注意只回复翻译的内容不要包含其他任何内容" + prompt);

        HttpURLConnection connection = null;

        // 使用 SseEmitter 来进行流式响应
        SseEmitter emitter = new SseEmitter();

        try {
            //查询url
            URL url = new URL(remoteLargeModelVo.getConfigValue() + "/api/generate");
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setDoOutput(true);

            // 发送请求数据
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = data.toString().getBytes("UTF-8");
                os.write(input, 0, input.length);
            }

            // 检查响应码
            int status = connection.getResponseCode();
            if (status != HttpURLConnection.HTTP_OK) {
                throw new IOException("HTTP request failed with status code " + status);
            }

            // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
            try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                String line;
                while ((line = br.readLine()) != null) {
                    JSONObject body = new JSONObject(line);
                    String responseText = body.getStr("response", "");

                    // 发送数据到前端
                    emitter.send(responseText, MediaType.TEXT_PLAIN);

                    // 检查是否有错误信息
                    if (body.containsKey("error")) {
                        throw new IOException("Error in response: " + body.getStr("error"));
                    }
                }
            }

        } catch (Exception e) {
            emitter.completeWithError(e);  // 出现异常时，通知前端
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }

        // 完成后端响应
        emitter.complete();
        return emitter;

    }


    /**
     * AI摘要
     * @param userMessage
     * @return
     * @throws IOException
     */
    @SneakyThrows
    @PostMapping("/documentary/abstract")
    public SseEmitter getDocumentaryAbstract(@RequestBody UserMessage userMessage) throws IOException {

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(userMessage.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        String prompt = null;

        switch (userMessage.getFileType().toLowerCase()) {
            case "txt":
                prompt = ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readTextFile(fileUrl);
                break;
            case "pdf":
//                prompt = ReaderUtil.readPdf(fileUrl);
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "docx":
            case "doc":
                prompt = ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readWord(fileUrl);
                break;
            case "xlsx":
            case "xls":
                prompt = ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readExcel(fileUrl);
                break;
            case "pptx":
            case "ppt":
                prompt = ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + userMessage.getFileType());
        }
        //查询模型
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();

//        String checkType = remoteLargeModelService.selectConfigByKey("check_type");
//        String model = remoteLargeModelService.selectConfigByTypeKey("model", checkType);
//        String ollamaUrl = remoteLargeModelService.selectConfigByTypeKey("url", checkType);

        // 创建用于 POST 请求的 data 对象
        JSONObject data = new JSONObject();
        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", true);
        data.set("prompt", "请对后面的内容进行摘要，注意只回复摘要的内容不要包含其他任何内容" + prompt);

        HttpURLConnection connection = null;

        // 使用 SseEmitter 来进行流式响应
        SseEmitter emitter = new SseEmitter();

        try {
            URL url = new URL(remoteLargeModelVo.getConfigValue() + "/api/generate");
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setDoOutput(true);

            // 发送请求数据
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = data.toString().getBytes("UTF-8");
                os.write(input, 0, input.length);
            }

            // 检查响应码
            int status = connection.getResponseCode();
            if (status != HttpURLConnection.HTTP_OK) {
                throw new IOException("HTTP request failed with status code " + status);
            }

            // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
            try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                String line;
                while ((line = br.readLine()) != null) {
                    JSONObject body = new JSONObject(line);
                    String responseText = body.getStr("response", "");

                    // 发送数据到前端
                    emitter.send(responseText, MediaType.TEXT_PLAIN);

                    // 检查是否有错误信息
                    if (body.containsKey("error")) {
                        throw new IOException("Error in response: " + body.getStr("error"));
                    }
                }
            }

        } catch (Exception e) {
            emitter.completeWithError(e);
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }

        // 完成后端响应
        emitter.complete();
        return emitter;

    }

    /**
     * AI提取
     * @param userMessage
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    @PostMapping("/documentary/extract")
    public SseEmitter getDocumentaryExtract(@RequestBody UserMessage userMessage) throws IOException, InterruptedException {

        // 获取文件的url
        String fileUrl = remoteFileService.selectUrlByIds(userMessage.getStorageId());
        String markItDownUrl = remoteConfigService.selectConfigByKey("markitdown.baseUrl");
        markItDownUrl = markItDownUrl + "/markitdown";
        String prompt = null;

        switch (userMessage.getFileType().toLowerCase()) {
            case "txt":
                prompt = ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readTextFile(fileUrl);
                break;
            case "pdf":
//                prompt = ReaderUtil.readPdf(fileUrl);
                String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");
                prompt = ReaderUtil.minerUReadPdf(fileUrl, MinerUUrl);
                break;
            case "docx":
            case "doc":
                prompt = ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readWord(fileUrl);
                break;
            case "xlsx":
            case "xls":
                prompt = ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readExcel(fileUrl);
                break;
            case "pptx":
            case "ppt":
                prompt = ReaderUtil.markItDown(fileUrl, markItDownUrl);
//                prompt = ReaderUtil.readPpt(fileUrl);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported file type: " + userMessage.getFileType());
        }

        // 创建用于 POST 请求的 data 对象
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();

//        String checkType = remoteLargeModelService.selectConfigByKey("check_type");
//        String model = remoteLargeModelService.selectConfigByTypeKey("model", checkType);
//        String ollamaUrl = remoteLargeModelService.selectConfigByTypeKey("url", checkType);

        JSONObject data = new JSONObject();
        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", true);
        data.set("prompt", "请对后面的内容进行关键词的抽取，注意只回复抽取出的关键词不要包含其他任何内容" + prompt);

        HttpURLConnection connection = null;
        SseEmitter emitter = new SseEmitter();

        try {
            URL url = new URL(remoteLargeModelVo.getConfigValue() + "/api/generate");
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setDoOutput(true);

            // 发送请求数据
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = data.toString().getBytes("UTF-8");
                os.write(input, 0, input.length);
            }

            // 检查响应码
            int status = connection.getResponseCode();
            if (status != HttpURLConnection.HTTP_OK) {
                throw new IOException("HTTP request failed with status code " + status);
            }

            // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
            try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                String line;
                while ((line = br.readLine()) != null) {
                    JSONObject body = new JSONObject(line);
                    String responseText = body.getStr("response", "");

                    // 发送数据到前端
                    emitter.send(responseText, MediaType.TEXT_PLAIN);

                    // 检查是否有错误信息
                    if (body.containsKey("error")) {
                        throw new IOException("Error in response: " + body.getStr("error"));
                    }
                }
            }

        } catch (Exception e) {
            emitter.completeWithError(e);
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }

        // 完成后端响应
        emitter.complete();
        return emitter;

    }

    /**
     * 文档问答总结功能
     * @param userMessage
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    @PostMapping("/documentary/file/summarize")
    public SseEmitter getDocumentaryFileSummarize(@RequestBody UserMessage userMessage) throws IOException, InterruptedException {

        // 创建用于 POST 请求的 data 对象
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();

//        String checkType = remoteLargeModelService.selectConfigByKey("check_type");
//        String model = remoteLargeModelService.selectConfigByTypeKey("model", checkType);
//        String ollamaUrl = remoteLargeModelService.selectConfigByTypeKey("url", checkType);

        JSONObject data = new JSONObject();
        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", true);
        data.set("prompt", "请对后面的内容进行总结，注意只回复总结的内容不要包含其他任何内容" + userMessage.getPrompt());

        HttpURLConnection connection = null;
        SseEmitter emitter = new SseEmitter();

        try {
            URL url = new URL(remoteLargeModelVo.getConfigValue() + "/api/generate");
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setDoOutput(true);

            // 发送请求数据
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = data.toString().getBytes("UTF-8");
                os.write(input, 0, input.length);
            }

            // 检查响应码
            int status = connection.getResponseCode();
            if (status != HttpURLConnection.HTTP_OK) {
                throw new IOException("HTTP request failed with status code " + status);
            }

            // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
            try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                emitter.send("message_start", MediaType.TEXT_PLAIN);
                String line;
                while ((line = br.readLine()) != null) {
                    JSONObject body = new JSONObject(line);
                    String responseText = body.getStr("response", "");

                    // 发送数据到前端
                    emitter.send(responseText, MediaType.TEXT_PLAIN);

                    // 检查是否有错误信息
                    if (body.containsKey("error")) {
                        throw new IOException("Error in response: " + body.getStr("error"));
                    }
                }
            }
            emitter.send("message_end");

        } catch (Exception e) {
            emitter.completeWithError(e);
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }

        // 完成后端响应
        emitter.complete();
        return emitter;
    }


    /**
     * 文档问答翻译功能
     * @param userMessage
     * @return
     */
    @PostMapping("/documentary/file/translation")
    public SseEmitter getDocumentaryFileTranslation(@RequestBody UserMessage userMessage) {

        // 创建用于 POST 请求的 data 对象
        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();

//        String checkType = remoteLargeModelService.selectConfigByKey("check_type");
//        String model = remoteLargeModelService.selectConfigByTypeKey("model", checkType);
//        String ollamaUrl = remoteLargeModelService.selectConfigByTypeKey("url", checkType);

        JSONObject data = new JSONObject();
        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("stream", true);
        data.set("prompt", "请对后面的内容进行翻译，注意只回复翻译的内容不要包含其他任何内容" + userMessage.getPrompt());

        HttpURLConnection connection = null;
        SseEmitter emitter = new SseEmitter();

        try {
            URL url = new URL(remoteLargeModelVo.getConfigValue() + "/api/generate");
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setDoOutput(true);

            // 发送请求数据
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = data.toString().getBytes("UTF-8");
                os.write(input, 0, input.length);
            }

            // 检查响应码
            int status = connection.getResponseCode();
            if (status != HttpURLConnection.HTTP_OK) {
                throw new IOException("HTTP request failed with status code " + status);
            }

            // 逐行读取响应流，并通过 SseEmitter 发送每一行到前端
            try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                emitter.send("message_start", MediaType.TEXT_PLAIN);
                String line;
                while ((line = br.readLine()) != null) {
                    JSONObject body = new JSONObject(line);
                    String responseText = body.getStr("response", "");

                    // 发送数据到前端
                    emitter.send(responseText, MediaType.TEXT_PLAIN);

                    // 检查是否有错误信息
                    if (body.containsKey("error")) {
                        throw new IOException("Error in response: " + body.getStr("error"));
                    }
                }
            }
            emitter.send("message_end");

        } catch (Exception e) {
            emitter.completeWithError(e);
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }

        // 完成后端响应
        emitter.complete();
        return emitter;
    }


    /**
     * AI普通问答
     * @param userMessage
     * @return
     */
    @PostMapping("/documentary/qa")
    public SseEmitter getDocumentaryQa(@RequestBody UserMessage userMessage) {

        JSONArray objects = userMessage.getHistory() != null ? new JSONArray(userMessage.getHistory()) : new JSONArray();
        JSONObject userMessageJson = new JSONObject();
        userMessageJson.set("role", "user");
//        userMessageJson.set("content", "你现在是一个AI问答助手，任务是根据用户的问题进行回答。" + "注意回答的内容为markdown格式");
        userMessageJson.set("content", "你现在是一个AI问答助手，任务是根据用户的问题进行回答。" +
            "如果用户的问题是要求直接对文档的内容进行处理，那么你就将文档的内容按照用户的问题进行处理然后直接回复给用户，例如用户要求将文档的内容翻译为英文那么你就将文档的内容翻译成英文回复给用户" +
            "如果文档内容能够回答用户的问题，用文档中总结的内容来回答问题。" +
            "如果文档内容无法回答用户的问题，则直接回复文档中没有具体的答案"
            + "用户的问题：" + userMessage.getContent()
            + "文档的内容：" + userMessage.getPrompt() + "注意你回复的内容是干净的markdown文本");
        objects.add(userMessageJson);

        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();

//        String checkType = remoteLargeModelService.selectConfigByKey("check_type");
//        String model = remoteLargeModelService.selectConfigByTypeKey("model", checkType);
//        String ollamaUrl = remoteLargeModelService.selectConfigByTypeKey("url", checkType);

        JSONObject data = new JSONObject();
        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("messages", objects);
        data.set("stream", true);

        HttpURLConnection connection = null;
        SseEmitter emitter = new SseEmitter();

        try {
            URL url = new URL(remoteLargeModelVo.getConfigValue() + "/api/chat");
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setDoOutput(true);

            // 发送请求数据
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = data.toString().getBytes("UTF-8");
                os.write(input, 0, input.length);
            }

            // 检查响应码
            int status = connection.getResponseCode();
            if (status != HttpURLConnection.HTTP_OK) {
                throw new IOException("HTTP request failed with status code " + status);
            }

            try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                String line;
                while ((line = br.readLine()) != null) {
//                    JSONObject body = new JSONObject(line);
//                    JSONObject message = body.getJSONObject("message");
//                    String responseText = message.getStr("content");

//                    emitter.send(responseText, MediaType.TEXT_MARKDOWN);
                    emitter.send(SseEmitter.event().data(line));

//                    if (body.containsKey("error")) {
//                        throw new IOException("Error in response: " + body.getStr("error"));
//                    }
                }
            }
        } catch (Exception e) {
            emitter.completeWithError(e);
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }

        // 完成后端响应
        emitter.complete();
        return emitter;
    }


//    @PostMapping("/documentary/qa")
//    public SseEmitter getDocumentaryQa(@RequestParam("file") MultipartFile file, @RequestParam("content") String content, @RequestParam("history") Object history) throws IOException, InterruptedException {
//
//        String originalFilename = file.getOriginalFilename();
//
//        // 获取扩展名 (即文件类型)
//        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.') + 1).toLowerCase();
////        userMessage.setFileType(fileExtension);
//
//        String prompt = null;
//
//        switch (fileExtension.toLowerCase()) {
//            case "txt":
//                prompt = ReaderUtil.fileReadTextFile(file);
//                break;
//            case "pdf":
//                prompt = ReaderUtil.minerUFileReadPdf(file);
//                break;
//            case "docx":
//                prompt = ReaderUtil.fileReadWord(file);
//                break;
//            case "xlsx":
//                prompt = ReaderUtil.fileReadExcel(file);
//                break;
//            case "pptx":
//                prompt = ReaderUtil.fileReadPpt(file);
//                break;
//            default:
//                throw new UnsupportedOperationException("Unsupported file type: " + fileExtension);
//        }
//
//        JSONArray objects = history != null ? new JSONArray(history) : new JSONArray();
//        JSONObject userMessageJson = new JSONObject();
//        userMessageJson.set("role", "user");
//        userMessageJson.set("content", "你现在是一个AI问答助手，任务是根据用户的问题进行回答。" +
//            "如果用户的问题是要求直接对文档的内容进行处理，那么你就将文档的内容按照用户的问题进行处理然后直接回复给用户，例如用户要求将文档的内容翻译为英文那么你就将文档的内容翻译成英文回复给用户" +
//            "如果文档内容能够回答用户的问题，用文档中总结的内容来回答问题。" +
//            "如果文档内容无法回答用户的问题，则直接回复文档中没有具体的答案"
//            + "用户的问题：" + content
//            + "文档的内容：" + prompt);
//        objects.add(userMessageJson);
//
//        String checkType = remoteLargeModelService.selectConfigByKey("check_type");
//        String model = remoteLargeModelService.selectConfigByTypeKey("model", checkType);
//        String ollamaUrl = remoteLargeModelService.selectConfigByTypeKey("url", checkType);
//        JSONObject data = new JSONObject();
//        data.set("model", model);
//        data.set("messages", objects);
//        data.set("stream", true);
//
//        HttpURLConnection connection = null;
//        SseEmitter emitter = new SseEmitter();
//
//        try {
//            URL url = new URL(ollamaUrl + "/api/chat");
//            connection = (HttpURLConnection) url.openConnection();
//            connection.setRequestMethod("POST");
//            connection.setRequestProperty("Content-Type", "application/json");
//            connection.setDoOutput(true);
//
//            // 发送请求数据
//            try (OutputStream os = connection.getOutputStream()) {
//                byte[] input = data.toString().getBytes("UTF-8");
//                os.write(input, 0, input.length);
//            }
//
//            // 检查响应码
//            int status = connection.getResponseCode();
//            if (status != HttpURLConnection.HTTP_OK) {
//                throw new IOException("HTTP request failed with status code " + status);
//            }
//
//            try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
//                emitter.send("message_start", MediaType.TEXT_PLAIN);
//                String line;
//                while ((line = br.readLine()) != null) {
//                    JSONObject body = new JSONObject(line);
//                    JSONObject message = body.getJSONObject("message");
//                    String responseText = message.getStr("content");
////                    String responseText = body.getStr("response", "");
//
//                    emitter.send(responseText, MediaType.TEXT_PLAIN);
//
//                    if (body.containsKey("error")) {
//                        throw new IOException("Error in response: " + body.getStr("error"));
//                    }
//                }
//            }
//            emitter.send("message_end");
//        } catch (Exception e) {
//            emitter.completeWithError(e);
//        } finally {
//            if (connection != null) {
//                connection.disconnect();
//            }
//        }
//
//        // 完成后端响应
//        emitter.complete();
//        return emitter;
//    }

    /**
     * 解析上传附件的内容
     * @param file
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    @PostMapping("/analyzeFileContent")
    public R<AnalyzeFileDto> analyzeFileContent(@RequestParam("file") MultipartFile file, String fileName) throws IOException, InterruptedException {

        String MinerUUrl = remoteConfigService.selectConfigByKey("minerU.baseUrl");

        QaFilesTree qaFilesTree = qaFilesTreeService.getOne(new LambdaQueryWrapper<QaFilesTree>()
            .eq(QaFilesTree::getRealName, fileName)
            .orderByDesc(QaFilesTree::getCreateTime).last("LIMIT 1"));

        String originalFilename = file.getOriginalFilename();
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.') + 1).toLowerCase();
        String prompt = null;
        switch (fileExtension.toLowerCase()) {
            case "txt":
                prompt = ReaderUtil.fileReadTextFile(file);
                AnalyzeFileDto analyzeFileDto = new AnalyzeFileDto();
                analyzeFileDto.setPrompt(prompt);
                analyzeFileDto.setFileId(qaFilesTree.getId());
                return R.ok(analyzeFileDto);
            case "pdf":
                prompt = ReaderUtil.minerUFileReadPdf(file, MinerUUrl);
                AnalyzeFileDto analyzeFileDtoPDF = new AnalyzeFileDto();
                analyzeFileDtoPDF.setPrompt(prompt);
                analyzeFileDtoPDF.setFileId(qaFilesTree.getId());
                return R.ok(analyzeFileDtoPDF);
            case "docx":
                //查询MinerU
                prompt = ReaderUtil.fileReadWord(file);
                AnalyzeFileDto analyzeFileDtoWord = new AnalyzeFileDto();
                analyzeFileDtoWord.setPrompt(prompt);
                analyzeFileDtoWord.setFileId(qaFilesTree.getId());
                return R.ok(analyzeFileDtoWord);
            case "xlsx":
                prompt = ReaderUtil.fileReadExcel(file);
                AnalyzeFileDto analyzeFileDtoExcel = new AnalyzeFileDto();
                analyzeFileDtoExcel.setPrompt(prompt);
                analyzeFileDtoExcel.setFileId(qaFilesTree.getId());
                return R.ok(analyzeFileDtoExcel);
            case "pptx":
                prompt = ReaderUtil.fileReadPpt(file);
                AnalyzeFileDto analyzeFileDtoPPT = new AnalyzeFileDto();
                analyzeFileDtoPPT.setPrompt(prompt);
                analyzeFileDtoPPT.setFileId(qaFilesTree.getId());
                return R.ok(analyzeFileDtoPPT);
            default:
                throw new UnsupportedOperationException("不支持的文件类型" + fileExtension);
        }
    }




    @PostMapping("/qa")
    public SseEmitter getQa(@RequestBody UserMessage userMessage) throws IOException {
        JSONArray objects = userMessage.getHistory() != null ? new JSONArray(userMessage.getHistory()) : new JSONArray();
        JSONObject userMessageJson = new JSONObject();
        userMessageJson.set("role", "user");
        userMessageJson.set("content", userMessage.getContent() + "注意你回答的内容是干净的markdown文本");
        objects.add(userMessageJson);


        RemoteLargeModelVo remoteLargeModelVo = remoteLargeModelService.selectRemoteDefault();

//        String checkType = remoteLargeModelService.selectConfigByKey("check_type");
//        String model = remoteLargeModelService.selectConfigByTypeKey("model", checkType);
//        String ollamaUrl = remoteLargeModelService.selectConfigByTypeKey("url", checkType);

        JSONObject data = new JSONObject();
        data.set("model", remoteLargeModelVo.getConfigKey());
        data.set("messages", objects);
        data.set("stream", true);

        HttpURLConnection connection = null;
        SseEmitter emitter = new SseEmitter();

        try {
            URL url = new URL(remoteLargeModelVo.getConfigValue() + "/api/chat");
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setDoOutput(true);

            // 发送请求数据
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = data.toString().getBytes("UTF-8");
                os.write(input, 0, input.length);
            }

            // 检查响应码
            int status = connection.getResponseCode();
            if (status != HttpURLConnection.HTTP_OK) {
                throw new IOException("HTTP request failed with status code " + status);
            }

            try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                String line;
                while ((line = br.readLine()) != null) {
//                    JSONObject body = new JSONObject(line);
//                    JSONObject message = body.getJSONObject("message");
//                    String responseText = message.getStr("content");

//                    emitter.send(responseText);
//                    emitter.send(SseEmitter.event().data(responseText));
                    emitter.send(SseEmitter.event().data(line));

//                    if (body.containsKey("error")) {
//                        throw new IOException("Error in response: " + body.getStr("error"));
//                    }
                }
            }
            emitter.complete();
        } catch (Exception e) {
            emitter.completeWithError(e);
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }

        // 完成后端响应
        emitter.complete();
        return emitter;
    }









    //=====================================================langchain实现==================================================================

    /**
     * 个人文档总结
     * @param storageId
     * @return
     */
//    @GetMapping("/document/summary")
//    public void getDocumentSummary(String storageId, String suffix, HttpServletResponse response) throws IOException, InterruptedException {
//        String fileUrl = remoteFileService.selectUrlByIds(storageId);
//        JSONObject jsonRequest = new JSONObject();
//        jsonRequest.put("fileUrl", fileUrl);
//        jsonRequest.put("suffix", suffix);
//        //调用langchain总结服务
//        String url = "http://localhost:5000/summarize";
//        HttpClient httpClient = HttpClient.newHttpClient();
//        HttpRequest request = HttpRequest.newBuilder()
//            .uri(URI.create(url))
//            .header("Content-Type", "application/json")
//            .POST(HttpRequest.BodyPublishers.ofString(jsonRequest.toString()))
//            .build();
//        HttpResponse<InputStream> responseStream  = httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
//
//        //设置sse响应头
//        response.setContentType("text/event-stream");
//        response.setCharacterEncoding("UTF-8");
//
//        try (BufferedReader reader = new BufferedReader(new InputStreamReader(responseStream.body()))) {
//            String line;
//            while ((line = reader.readLine()) != null) {
//                // 每行数据作为事件发送
//                response.getWriter().write("data: " + line + "\n\n");
//                response.getWriter().flush();
//                Thread.sleep(100);  // 模拟打字效果的延迟，按需调整
//            }
//        }
//
//    }


    /**
     * 个人文档翻译
     * @param storageId
     * @param response
     * @throws IOException
     * @throws InterruptedException
     */
//    @GetMapping("/documentary/translation")
//    public void getDocumentaryTranslation(String storageId, String suffix, HttpServletResponse response) throws IOException, InterruptedException {
//        String fileUrl = remoteFileService.selectUrlByIds(storageId);
//        JSONObject jsonRequest = new JSONObject();
//        jsonRequest.put("fileUrl", fileUrl);
//        jsonRequest.put("suffix", suffix);
//        //调用langchain翻译服务
//        String url = "http://localhost:5000/translation";
//        HttpClient httpClient = HttpClient.newHttpClient();
//        HttpRequest request = HttpRequest.newBuilder()
//            .uri(URI.create(url))
//            .header("Content-Type", "application/json")
//            .POST(HttpRequest.BodyPublishers.ofString(jsonRequest.toString()))
//            .build();
//        HttpResponse<InputStream> responseStream  = httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
//
//        //设置sse响应头
//        response.setContentType("text/event-stream");
//        response.setCharacterEncoding("UTF-8");
//
//        try (BufferedReader reader = new BufferedReader(new InputStreamReader(responseStream.body()))) {
//            String line;
//            while ((line = reader.readLine()) != null) {
//                // 每行数据作为事件发送
//                response.getWriter().write("data: " + line + "\n\n");
//                response.getWriter().flush();
//                Thread.sleep(100);  // 模拟打字效果的延迟，按需调整
//            }
//        }
//    }

    /**
     * 个人文档摘要
     * @param storageId
     * @param suffix
     * @param response
     * @throws IOException
     * @throws InterruptedException
     */
//    @GetMapping("/documentary/abstract")
//    public void getDocumentaryAbstract(String storageId, String suffix, HttpServletResponse response) throws IOException, InterruptedException {
//        String fileUrl = remoteFileService.selectUrlByIds(storageId);
//        JSONObject jsonRequest = new JSONObject();
//        jsonRequest.put("fileUrl", fileUrl);
//        jsonRequest.put("suffix", suffix);
//
//        String url = "http://localhost:5000/abstract";
//        HttpClient httpClient = HttpClient.newHttpClient();
//        HttpRequest request = HttpRequest.newBuilder()
//            .uri(URI.create(url))
//            .header("Content-Type", "application/json")
//            .POST(HttpRequest.BodyPublishers.ofString(jsonRequest.toString()))
//            .build();
//        HttpResponse<InputStream> responseStream  = httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
//
//
//        response.setContentType("text/event-stream");
//        response.setCharacterEncoding("UTF-8");
//
//        try (BufferedReader reader = new BufferedReader(new InputStreamReader(responseStream.body()))) {
//            String line;
//            while ((line = reader.readLine()) != null) {
//
//                response.getWriter().write("data: " + line + "\n\n");
//                response.getWriter().flush();
//                Thread.sleep(100);
//            }
//        }
//    }

    /**
     * 个人文档抽取关键词
     * @param storageId
     * @param suffix
     * @param response
     * @throws IOException
     * @throws InterruptedException
     */
//    @GetMapping("/documentary/extract")
//    public void getDocumentaryExtract(String storageId, String suffix, HttpServletResponse response) throws IOException, InterruptedException {
//        String fileUrl = remoteFileService.selectUrlByIds(storageId);
//        JSONObject jsonRequest = new JSONObject();
//        jsonRequest.put("fileUrl", fileUrl);
//        jsonRequest.put("suffix", suffix);
//
//        String url = "http://localhost:5000/extract";
//        HttpClient httpClient = HttpClient.newHttpClient();
//        HttpRequest request = HttpRequest.newBuilder()
//            .uri(URI.create(url))
//            .header("Content-Type", "application/json")
//            .POST(HttpRequest.BodyPublishers.ofString(jsonRequest.toString()))
//            .build();
//        HttpResponse<InputStream> responseStream  = httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
//
//
//        response.setContentType("text/event-stream");
//        response.setCharacterEncoding("UTF-8");
//
//        try (BufferedReader reader = new BufferedReader(new InputStreamReader(responseStream.body()))) {
//            String line;
//            while ((line = reader.readLine()) != null) {
//
//                response.getWriter().write("data: " + line + "\n\n");
//                response.getWriter().flush();
//                Thread.sleep(100);
//            }
//        }
//    }

    /**
     * 个人文档问答
     * @param file
     * @param response
     * @throws IOException
     * @throws InterruptedException
     */
//    @GetMapping("/documentary/qa")
//    public void getDocumentaryQa(@RequestParam("file") MultipartFile file, HttpServletResponse response) throws IOException, InterruptedException {
//
//
//        String url = "http://localhost:5000/qa";
//
//    }




}
